﻿using PivotData;
using PivotIO.XML;
using PivotWebsite.MediaFormatters;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Web.Http;

namespace PivotWebsite.Controllers
{
    public class ImagesController : ApiController
    {
        /// <summary>
        /// Cache an image under a certian name.
        /// </summary>
        /// <param name="collectionId"></param>
        /// <param name="iName"></param>
        /// <param name="image"></param>
        public ImageInfo PutImage(int cId, [FromUri] string iName, [FromBody] ImageFormatter.BinaryImage image)
        {
            //
            // Make sure this is a reasonable request
            //

            var cl = CollectionInfoIO.LoadCollection(cId);
            if (cl == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            var images = ImageInfoIO.LoadAllImages(cId);

            //
            // Same image or a new one?
            //

            var oldImage = images.Where(i => i.Name == iName).FirstOrDefault();
            var newImage = new ImageInfo();
            if (oldImage != null)
            {
                newImage = oldImage;
            }
            else
            {
                int maxV = 0;
                if (images.Length > 0)
                    maxV = images.Max(i => i.Id);

                newImage = new ImageInfo() { Name = iName, Id = maxV + 1, Extension = image.metaData };
            }

            ImageInfoIO.SaveImage(cId, newImage.Id, newImage.Extension, image.data);

            if (oldImage == null)
                ImageInfoIO.SaveAllImages(cId, images.Concat(new ImageInfo[] { newImage }).ToArray());

            return newImage;
        }

        /// <summary>
        /// Return a image.
        /// </summary>
        /// <param name="cId"></param>
        /// <param name="iId"></param>
        /// <returns></returns>
        public HttpResponseMessage GetImage(int cId, int iId)
        {
            var cl = CollectionInfoIO.LoadCollection(cId);
            if (cl == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            var img = ImageInfoIO.LoadAllImages(cId).Where(i => i.Id == iId).FirstOrDefault();
            if (img == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            var iFIO = new FileInfo(Path.Combine(Utils.GetROOTDataDirectory().FullName, cId.ToString(), string.Format("{0}.{1}", iId.ToString(), img.Extension)));
            if (!iFIO.Exists)
            {
                // Yikes! Corrupt!
                return null;
            }

            var b = new ImageFormatter.BinaryImage();
            b.metaData = img.Extension;
            b.data = new byte[iFIO.Length];

            using (var input = iFIO.OpenRead())
            {
                input.Read(b.data, 0, (int)iFIO.Length);
            }

            return Request.CreateResponse(HttpStatusCode.OK, b, string.Format("image/{0}", b.metaData));
        }

        /// <summary>
        /// Return all images - info - in the collection. By default we don't return the
        /// facet list.
        /// </summary>
        /// <param name="cId">Collection ID from which you want all images</param>
        /// <param name="withFacets">If set then will return facet information. This can make for a very large payload coming back and take quite a while. By default this is false.</param>
        /// <returns></returns>
        public ImageInfo[] GetImages(int cId, bool withFacets = false)
        {
            var cl = CollectionInfoIO.LoadCollection(cId);
            if (cl == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            var imgData = ImageInfoIO.LoadAllImages(cId);
            if (!withFacets)
            {
                imgData = imgData.Select(i => new ImageInfo(i)).ToArray();
                foreach (var i in imgData)
                {
                    i.Facets = null;
                }
            }

            return imgData;
        }

        /// <summary>
        /// Return all iamges that match the regex that is in name.
        /// </summary>
        /// <param name="cId"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public ImageInfo[] GetImages(int cId, string name)
        {
            var cl = CollectionInfoIO.LoadCollection(cId);
            if (cl == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            var finder = new Regex(name);

            return ImageInfoIO.LoadAllImages(cId).Where(i => finder.Match(i.Name).Success).ToArray();
        }
    }
}
